package org.feng.navigation.common.util;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;

import java.util.Map;

/**
 * 使用Gson处理Json数据格式的工具类
 *
 * @version V1.0
 * @author: junzi
 * @date: 2022年02月09日 17时05分
 */
public class GsonUtil {
    /**
     * 不会序列化空字段的Gson对象
     */
    private static final Gson GSON = new GsonBuilder().create();
    /**
     * 可以序列化空字段的Gson对象
     */
    private static final Gson GSON_WITH_NULL = new GsonBuilder().serializeNulls().create();

    private static final Gson GSON_WITH_DISABLE_HTML_ESCAPING = new GsonBuilder().disableHtmlEscaping().create();

    public static Gson gson() {
        return GSON;
    }

    /**
     * 转换对象为json字符串（不会序列化空字段）
     *
     * @param object 目标对象
     * @return 一个json字符串
     */
    public static String toJson(Object object) {
        return GSON.toJson(object);
    }

    /**
     * 转换对象为json字符串（可以序列化空字段）
     *
     * @param object 目标对象
     * @return 一个json字符串
     */
    public static String toJsonWithNull(Object object) {
        return GSON_WITH_NULL.toJson(object);
    }

    /**
     * 转换对象为json字符串（禁止html转义）
     *
     * @param object 目标对象
     * @return 一个json字符串
     */
    public static String toJsonWithDisableTtmlEscaping(Object object) {
        return GSON_WITH_DISABLE_HTML_ESCAPING.toJson(object);
    }

    public static <T> T fromJson(String jsonStr, Class<T> clazz) {
        return GSON.fromJson(jsonStr, clazz);
    }

    /**
     * 校验字符串是否是一个json格式
     * <br> 注意：{@code "{}"} 也是符合条件的json
     *
     * @param jsonStr 目标字符串
     * @return true表示目标是一个正确的json格式
     */
    public static boolean validateJson(String jsonStr) {
        JsonElement jsonElement;
        try {
            jsonElement = JsonParser.parseString(jsonStr);
        } catch (Exception e) {
            return false;
        }
        if (jsonElement == null) {
            return false;
        }
        return jsonElement.isJsonObject();
    }

    /**
     * 将一个json字符串转换为 Map。（不适用与json数组）<br><b>本方法适用于简单层级的json串。</b>
     * <br>
     * 注意：所有的数值类型，适用Object接收时，会自动转换为 double 类型
     *
     * @param jsonStr json字符串
     * @return 一个Map对象
     */
    public static Map<String, Object> parseToObjectMap(String jsonStr) {
        return gson().fromJson(jsonStr, new TypeToken<Map<String, Object>>() {
        }.getType());
    }

    /**
     * 将一个json字符串转换为 Map。（不适用与json数组）<br><b>本方法适用于简单层级的json串。</b>
     * <br>
     * 注意：所有的数值类型，会按照原有类型转换。
     *
     * @param jsonStr json字符串
     * @return 一个Map对象
     */
    public static Map<String, String> parseToStringMap(String jsonStr) {
        return gson().fromJson(jsonStr, new TypeToken<Map<String, String>>() {
        }.getType());
    }

    private GsonUtil() {
    }
}
